import {bus} from '@beshell/events-ts/bus'
import { conn } from '@beshell/conn-ts/Connection'
import {AppModel} from '../AppModel'
import { Stud } from '../Stud'
import { isGPIOPin, Usage } from '../StudUsage'
import { PartSlaver } from './PartBase'
import config from './config/BeSwitch.json'

export class BeSwitch extends PartSlaver {

    protected inputProvider: Stud|null = null
    protected outputProvider: Stud|null = null

    public isOn = false

    constructor(_model: AppModel){
        super(_model, config)

        bus.on("remote.part.event", (partIns:string, isOn: boolean)=>{
            if(partIns!=this.instanceName) {
                return
            }
            // Vue.prototype.$set(this, 'isOn', isOn)
            this.isOn = isOn
        })
    }

    private resolveProviders() {
        this.inputProvider = null
        this.outputProvider = null

        let pin0 = (this.studs[0][0].bus && this.studs[0][0].bus.findHostStud()) || null 
        let pin1 = (this.studs[0][1].bus && this.studs[0][1].bus.findHostStud()) || null 

        if(pin0 && !isGPIOPin(pin0)) {
            this.outputProvider = pin0
            this.inputProvider = pin1
        }
        else if(pin1 && !isGPIOPin(pin1)) {
            this.outputProvider = pin1
            this.inputProvider = pin0
        }
        else {
            this.outputProvider = pin1
            this.inputProvider = pin0
        }
    }

    public generateSetupCode(indent=0){
        return `${"\t".repeat(indent)}${this.remoteVar()} = new (require('besdk/driver/switch.js')) ()`
    }

    private pinName(pin:Stud|null){
        if(pin) {
            if(isGPIOPin(pin)) {
                return pin.gpio.name()
            }
            if( pin.info.usages.includes(Usage.ground) ){
                return "'ground'"
            }
            if( pin.info.usages.includes(Usage.vcc) || pin.info.usages.includes(Usage.vm) || pin.info.usages.includes(Usage.reset) ){
                return "'vcc'"
            }
        }
        return 'undefined'
    }

    public generateBeginCode(indent=0){

        this.resolveProviders()
        if(!this.inputProvider)
            return ''
        let outputPinName = this.pinName(this.outputProvider)
        let inputPinName = this.pinName(this.inputProvider)
        return `${"\t".repeat(indent)}${this.remoteVar()}.begin( ${inputPinName}, ${outputPinName} )`
    }

    public async remoteSetup() {
        if(!conn.isConnected)
            return
        await conn.console.call(`${this.remoteVar()}.on("change",isOn=>telnet.callback('EmitPartEvent', '${this.instanceName}', isOn))`)
        let isOn = await conn.console.call(`${this.remoteVar()}.isOn()`)
        // Vue.prototype.$set(this, 'isOn', isOn)
        this.isOn = isOn
    }
    

    public isConnectionReady() {
        this.resolveProviders()
        console.log("switch is ready?", (!!this.inputProvider) && (!!this.outputProvider))
        return (!!this.inputProvider) && (!!this.outputProvider)
    }

    // public remote
}